﻿using System;
using System.IO;
using System.Linq;
using System.Transactions;
using System.Web.Mvc;
using qlqa.Delegate.FoodDelegate;
using qlqa.Delegate.HoaDonDelegate;
using qlqa.Delegate.TableDelegate;
using qlqa.Models.Form.HoaDonForm;
using qlqa.Models.Form.OrderForm;
using qlqa.Models.Form.TableForm;
using qlqa.Models.LinQ;

namespace qlqa.Controllers
{
    public class TableController : Controller
    {
        readonly TableDelegate _tableDelegate = new TableDelegate();
        readonly HoaDonDelegate _hoaDonDelegate = new HoaDonDelegate();
        readonly FoodDelegate _foodDelegate = new FoodDelegate();
        
        /// <summary>
        /// Chuyển PartialView thành chuỗi HTML
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="viewPath"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        protected string RenderViewToString<T>(string viewPath, T model)
        {
            ViewData.Model = model;
            using (var writer = new StringWriter())
            {
                var view = new WebFormView(viewPath);
                var vdd = new ViewDataDictionary<T>(model);
                var viewCxt = new ViewContext(ControllerContext, view, vdd,
                                            new TempDataDictionary(), writer);
                viewCxt.View.Render(viewCxt, writer);
                return writer.ToString();
            }
        }

        #region Quản lý Bàn
        /// <summary>
        /// View bàn ăn
        /// </summary>
        /// <returns></returns>
        public ActionResult QlTable()
        {
            var form = new TableForm
            {
                ListTable = _tableDelegate.GetTables(null)
            };

            return View("BanAn",form);
        }

        /// <summary>
        /// Xem thông tin bàn ăn
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult InfoTable(int id)
        {
            tb_Ban table = _tableDelegate.GetTables(id)[0];

            var list = new SelectList(_tableDelegate.GetTrangThaiSuDungBan(),"Id","Ten");

            return Json(new {id = table.Id, ten = table.Ten, ghichu = table.GhiChu, sudung = table.IsSuDung, trangthai = table.TrangThaiSuDung, list });
        }

        /// <summary>
        /// Thêm bàn (refresh form)
        /// </summary>
        /// <param name="ten"></param>
        /// <param name="ghichu"></param>
        /// <param name="sudung"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult InsertTable(string ten, string ghichu, int sudung)
        {
            var newTable = new tb_Ban
            {
                Ten = ten, GhiChu = ghichu, IsSuDung = sudung == 1 ? true : false , IsDelete = false, NguoiTao = _tableDelegate.UserId, NgayTao = DateTime.Now
            };
            newTable.NgayTao = newTable.NgaySua = DateTime.Now;
            //newTable.NguoiTao = newTable.NguoiSua = Session["UserId"];
            var res = _tableDelegate.InsertTable(newTable);
            return Json(res);
        }

        /// <summary>
        /// Thêm bàn ajax
        /// </summary>
        /// <param name="ten"></param>
        /// <param name="ghichu"></param>
        /// <param name="sudung"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult InsertTableAjax(string ten, string ghichu, int sudung)
        {
            var newTable = new tb_Ban
            {
                Ten = ten,
                GhiChu = ghichu,
                IsSuDung = sudung == 1,
                IsDelete = false,
                NguoiTao = _tableDelegate.UserId,
                NgayTao = DateTime.Now
            };
            newTable.NgayTao = newTable.NgaySua = DateTime.Now;
            //newTable.NguoiTao = newTable.NguoiSua = Session["UserId"];
            var res = _tableDelegate.InsertTableReturnTable(newTable);
            return PartialView("Table",res);
        }

        /// <summary>
        /// Sửa bàn ăn
        /// </summary>
        /// <param name="id"></param>
        /// <param name="ten"></param>
        /// <param name="ghichu"></param>
        /// <param name="sudung"></param>
        /// <param name="trangthai"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult EditTable(int id,string ten, string ghichu, int sudung, int trangthai)
        {
            tb_Ban table = _tableDelegate.GetTables(id)[0];

            if (table != null)
            {
                var check = _hoaDonDelegate.KiemTraBanHienDangCoHoaDon(id);
                if (check)
                    return Json(new { res = false, trangthai });

                table.Ten = ten;
                table.GhiChu = ghichu;
                table.IsSuDung = (sudung == 1) ? true : false;
                table.TrangThaiSuDung = trangthai;
                table.NguoiSua = _tableDelegate.UserId;
                table.NgaySua = DateTime.Now;
            }
            var res = _tableDelegate.SaveChange();

            return Json(new{ res, trangthai });
        }

        /// <summary>
        /// Xóa bàn ăn
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult DeleteTable(int id)
        {
            tb_Ban table = _tableDelegate.GetTables(id)[0];

            var check = _hoaDonDelegate.KiemTraBanHienDangCoHoaDon(id);
            if (check)
                return Json(false);

            var res = _tableDelegate.DeleteTable(table);

            return Json(res);
        }
        #endregion

        #region Đặt bàn, gọi món
        /// <summary>
        /// Chọn bàn, gọi món
        /// </summary>
        /// <param name="id">id của bàn</param>
        /// <returns></returns>
        public ActionResult Order(int? id)
        {
            if (id == null)
                return RedirectToAction("QlTable");

            var ban = _tableDelegate.GetTables(id)[0];

            if (ban == null)
                return RedirectToAction("QlTable");

            var form = new OrderForm
            {
                Ban = ban,
                ListMonAn = _foodDelegate.GetFoodByType(null,null),
                GetOrSearch = true
            };

            //Kiểm tra bàn đã tạo hóa đơn hay chưa
            var check = _hoaDonDelegate.KiemTraBanHienDangCoHoaDon(id);
            if (check)
            {
                var hoaDon = _hoaDonDelegate.GetHoaDonTheoBan(id);
                form.HoaDon = hoaDon;
                form.ListChiTietHoaDon = _hoaDonDelegate.GetChiTietHoaDonTheoHoaDon(hoaDon.Id);

                if (form.Ban.TrangThaiSuDung != 2)
                {
                    _tableDelegate.ChuyenTrangThai(form.Ban.Id, 2);
                }
            }

            //Kiểm tra bàn ghép
            if (ban.IdBan != null && ban.IdBan > 0)
            {
                var check2 = _hoaDonDelegate.KiemTraBanHienDangCoHoaDon(ban.IdBan);
                if (check2)
                {
                    var hoaDon = _hoaDonDelegate.GetHoaDonTheoBan(ban.IdBan);
                    form.HoaDon = hoaDon;
                    form.ListChiTietHoaDon = _hoaDonDelegate.GetChiTietHoaDonTheoHoaDon(hoaDon.Id);
                    form.BanChinh = _tableDelegate.GetTable(ban.IdBan);
                    if (form.Ban.TrangThaiSuDung != 2)
                    {
                        _tableDelegate.ChuyenTrangThai(form.Ban.Id, 2);
                    }
                }
            }

            return View("Order", form);
        }

        /// <summary>
        /// Load dữ liệu chi tiết hóa đơn và thành tiền lên partial view
        /// </summary>
        /// <param name="idHoaDon"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult LoadOrderAjax(long? idHoaDon)
        {
            var form = new OrderForm();
            var hoadon = _hoaDonDelegate.GetHoaDon(idHoaDon);
            if (hoadon != null)
            {
                form.HoaDon = hoadon;
                form.ListChiTietHoaDon = _hoaDonDelegate.GetChiTietHoaDonTheoHoaDon(hoadon.Id);
                var html = RenderViewToString("~/Views/Table/OrderAjax.ascx", form);
                return Json(new { res = true, html });
            }
            return Json(new {res = false});
        }

        /// <summary>
        /// Thực hiện chọn món, tạo hóa đơn
        /// </summary>
        /// <param name="idHoaDon"></param>
        /// <param name="idBan"></param>
        /// <param name="idMon"></param>
        /// <param name="soluong"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult OrderAjax(long? idHoaDon, int? idBan, int? idMon, int? soluong)
        {
            if (idMon == null || idHoaDon == null || idBan == null)
            {
                return Json(new { res = false });
            }
            var form = new OrderForm();

            //Kiểm tra bàn và hóa đơn có không
            var ban = _tableDelegate.GetTables(idBan)[0];
            if (ban == null)
            {
                return Json(new { res = false });
            }
            var hoadon = _hoaDonDelegate.GetHoaDon(Convert.ToInt32(idHoaDon));
            string html;
            if (hoadon != null)
            {
                //if (ban.TrangThaiSuDung != 2)
                //{
                //    _tableDelegate.ChuyenTrangThai(ban.Id, 2);
                //}
                //using (var tran = new TransactionScope())
                //{
                    //Kiểm tra trạng thái hóa đơn, chưa tính tiền thì thêm món
                    if (hoadon.IsThanhToan == false || hoadon.IsThanhToan == null)
                    {
                        //Thêm chi tiết hóa đơn
                        var chiTietHoaDon = _hoaDonDelegate.CreateChiTietHoaDon(
                            hoadon.Id, hoadon.IdBan, Convert.ToInt32(idMon),
                            Convert.ToInt32(soluong));

                        if (chiTietHoaDon != null)
                        {
                            //Cập nhật thành tiền trong hóa đơn
                            _hoaDonDelegate.UpdateHoaDonThanhTien(hoadon.Id);
                            //Kiểm tra trạng thái bàn, gọi món thì chuyển trạng thái lên đang sử dụng
                            if (ban.TrangThaiSuDung != 2)
                                _tableDelegate.ChuyenTrangThai(Convert.ToInt32(idBan), 2);
                        }
                    }
                    //tran.Complete();
                    //tran.Dispose();

                    form.HoaDon = hoadon;
                    form.ListChiTietHoaDon = _hoaDonDelegate.GetChiTietHoaDonTheoHoaDon(hoadon.Id);
                    html = RenderViewToString("~/Views/Table/OrderAjax.ascx", form);

                    return Json(new { res = true, idHoaDon = hoadon.Id, html });
                //}
            }

            //Nếu chưa có hóa đơn thì tạo hóa đơn
            var hoaDonMoi = _hoaDonDelegate.CreateHoaDon(idBan);
            //using (var tranNew = new TransactionScope())
            //{
                //Kiểm tra trạng thái hóa đơn, chưa tính tiền thì thêm món
                if (hoaDonMoi.IsThanhToan == false || hoaDonMoi.IsThanhToan == null)
                {
                    //Thêm chi tiết hóa đơn
                    var chiTietHoaDon = _hoaDonDelegate.CreateChiTietHoaDon(
                        Convert.ToInt32(hoaDonMoi.Id), Convert.ToInt32(idBan), Convert.ToInt32(idMon),
                        Convert.ToInt32(soluong));

                    if (chiTietHoaDon != null)
                    {
                        //Cập nhật thành tiền trong hóa đơn
                        _hoaDonDelegate.UpdateHoaDonThanhTien(hoaDonMoi.Id);

                        //Kiểm tra trạng thái bàn, gọi món thì chuyển trạng thái lên đang sử dụng
                        if(ban.TrangThaiSuDung != 2)
                            _tableDelegate.ChuyenTrangThai(Convert.ToInt32(idBan), 2);
                    }
                }
                //tranNew.Complete();
                //tranNew.Dispose();

                form.HoaDon = hoaDonMoi;
                form.ListChiTietHoaDon = _hoaDonDelegate.GetChiTietHoaDonTheoHoaDon(hoaDonMoi.Id);
                html = RenderViewToString("~/Views/Table/OrderAjax.ascx", form);

                return Json(new { res = true, idHoaDon = hoaDonMoi.Id, html });
            //}
        }

        /// <summary>
        /// Hủy hóa đơn (khi không có món nào)
        /// </summary>
        /// <param name="idHoaDon"></param>
        /// <param name="idBan"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult HuyHoaDon(long? idHoaDon, int? idBan)
        {
            var hoadon = _hoaDonDelegate.HuyHoaDon(idHoaDon);
            if(hoadon)
                _tableDelegate.ChuyenTrangThai(Convert.ToInt32(idBan), 1);
            return Json(hoadon);
        }

        /// <summary>
        /// Xóa món đã chọn trong order
        /// </summary>
        /// <param name="idChiTiet"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult DeleteOrderAjax(long? idChiTiet)
        {
            var chiTiet = _hoaDonDelegate.GetChiTietHoaDon(Convert.ToInt64(idChiTiet));
            if (chiTiet != null)
            {
                var hoadon = _hoaDonDelegate.GetHoaDon(chiTiet.IdHoaDon);
                var res = _hoaDonDelegate.XoaMonTrongChiTietHoaDon(chiTiet.Id);
                if (res)
                {
                    //Cập nhật thành tiền trong hóa đơn
                    _hoaDonDelegate.UpdateHoaDonThanhTien(hoadon.Id);
                }
                return Json(res);
            }
            return Json(false);
        }

        /// <summary>
        /// Cập nhật order (giá cả, số lượng)
        /// </summary>
        /// <param name="arrayId"></param>
        /// <param name="arrayData"></param>
        /// <param name="arrayNumber"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult UpdateOrderAjax(string[] arrayId, string[] arrayData, string[] arrayNumber)
        {
            if (arrayData == null || arrayId == null || arrayNumber == null) return Json(false);

            if (arrayId.Any() && arrayData.Any() && arrayNumber.Any())
            {
                for (int i = 0; i < arrayId.Count(); i++)
                {
                    long id = Convert.ToInt64(arrayId[i]);
                    long gia = Convert.ToInt64(arrayData[i]);
                    int soluong = Convert.ToInt32(arrayNumber[i]);
                    _hoaDonDelegate.UpdateOrderd(id, gia, soluong);
                }
                return Json(true);
            }
            return Json(false);
        }

        /// <summary>
        /// Tải danh sách các bàn được ghép với bàn chính
        /// </summary>
        /// <param name="idBanChinh"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult MergeTablesOfTable(int idBanChinh)
        {
            var form = new OrderForm {ListBanGhep = _tableDelegate.GetMergeTables(idBanChinh)};
            
            return PartialView("MergedTable", form);
        }

        /// <summary>
        /// Gộp bàn
        /// </summary>
        /// <param name="idBan">id Bàn chính</param>
        /// <param name="arrayBan">id các bàn ghép</param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult GhepBanAjax(int? idBan, string[] arrayBan)
        {
            if (idBan != null)
            {
                if (arrayBan != null && arrayBan.Any())
                {
                    var hoaDon = _hoaDonDelegate.GetHoaDonTheoBan(idBan);
                    if (hoaDon != null)
                    {
                        if (hoaDon.IsThanhToan == null || hoaDon.IsThanhToan == false)
                        {
                            var str = string.Empty;
                            bool res;

                            for (var i = 0; i < arrayBan.Count(); i++)
                            {
                                str += arrayBan[i] + ",";
                                res = _tableDelegate.ChuyenTrangThaiGhepBan(idBan,Convert.ToInt32(arrayBan[i]), 2);
                                if (!res)
                                {
                                    return Json(false);
                                }
                            }
                                    
                            if (string.IsNullOrEmpty(hoaDon.ArrayBan))
                            {
                                hoaDon.ArrayBan = str;
                                res = _hoaDonDelegate.UpdateArrayBan(hoaDon);
                            }
                            else
                            {
                                if (hoaDon.ArrayBan[hoaDon.ArrayBan.Length - 1] != ',')
                                {
                                    hoaDon.ArrayBan += "," + str;
                                }
                                else
                                {
                                    hoaDon.ArrayBan += str;
                                }
                                res = _hoaDonDelegate.UpdateArrayBan(hoaDon);
                            }
                               
                            return Json(res);
                        }
                    }
                }
            }
            return Json(false);
        }

        /// <summary>
        /// Xóa bàn ghép
        /// </summary>
        /// <param name="idHoaDon"></param>
        /// <param name="idBan"></param>
        /// <param name="idBanRemove"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult DeleteGhepBanAjax(long? idHoaDon, int? idBan, int? idBanRemove)
        {
            if (idHoaDon != null && idBan != null && idBanRemove != null)
            {
                var res = _tableDelegate.DeleteMergedTable(idHoaDon,idBan,idBanRemove);
                return Json(res);
            }

            return Json(false);
        }

        /// <summary>
        /// Danh sách bàn trống có thể chọn, sử dụng
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult UsableTables()
        {
            var form = new OrderForm
            {
                ListBanTrong = _tableDelegate.GetUsableTables()
            };

            return PartialView("UsableTable", form);
        }

        #endregion

        #region Tính tiền, xuất hóa đơn
        /// <summary>
        /// Tính tiền của hóa đơn theo bàn
        /// </summary>
        /// <param name="idBan"></param>
        /// <param name="idHoaDon"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult TinhTien(int? idBan, long? idHoaDon)
        {
            if (idBan != null && idHoaDon != null)
            {
                var res = _hoaDonDelegate.TinhTienHoaDon(idHoaDon);
                return Json(res);
            }
            return Json(false);
        }

        public JsonResult ThongTinHoaDon(long? idHoaDon)
        {
            var form = new HoaDonForm();
            var hoaDon = _hoaDonDelegate.GetHoaDon(idHoaDon);
            form.HoaDon = hoaDon;
            form.DanhSachChiTietHoaDon = _hoaDonDelegate.GetChiTietHoaDonTheoHoaDon(hoaDon.Id);

            return Json(new { html = RenderViewToString("~/Views/HoaDon/ThongTinHoaDon.ascx", form) });
        }

        public ActionResult DanhSachHoaDon()
        {
            var form = new HoaDonForm();
            form.DanhSachHoaDon = _hoaDonDelegate.GetDanhSachHoaDon();

            return View("~/Views/HoaDon/DanhSachHoaDon.aspx", form);
        }

        [HttpPost]
        public JsonResult TimKiemHoaDon(HoaDonForm input)
        {
            var form = new HoaDonForm();
            form.DanhSachHoaDon = _hoaDonDelegate.LocHoaDon(input);

            return Json(new {html = RenderViewToString("~/Views/HoaDon/DanhSachHoaDonAjax.ascx", form)});
        }

        #endregion
    }
}
